package com.shopmall.order.service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.shopmall.common.exception.CustomException;
import com.shopmall.feign.cart.CartFeignClient;
import com.shopmall.feign.product.ProductFeignClient;
import com.shopmall.feign.user.UserFeignClient;
import com.shopmall.model.dto.h5.OrderInfoDto;
import com.shopmall.model.entity.h5.CartInfo;
import com.shopmall.model.entity.order.OrderInfo;
import com.shopmall.model.entity.order.OrderItem;
import com.shopmall.model.entity.order.OrderLog;
import com.shopmall.model.entity.product.ProductSku;
import com.shopmall.model.entity.user.UserAddress;
import com.shopmall.model.entity.user.UserInfo;
import com.shopmall.model.vo.common.ResultCodeEnum;
import com.shopmall.model.vo.h5.TradeVo;
import com.shopmall.order.mapper.OrderInfoMapper;
import com.shopmall.order.mapper.OrderItemMapper;
import com.shopmall.order.mapper.OrderLogMapper;
import com.shopmall.order.service.OrderInfoService;
import com.shopmall.utils.AuthContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;

@Service
public class OrderInfoServiceImpl implements OrderInfoService {
    @Autowired
    private CartFeignClient cartFeignClient;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private OrderLogMapper orderLogMapper;

    // 确认下单
    @Override
    public TradeVo getTrade() {
        // 远程调用获取购物车选中商品列表
        List<CartInfo> cartInfoList = cartFeignClient.getAllChecked();
        // 创建list集合用于封装订单项
        List<OrderItem> orderItemList = new ArrayList<>();
        for (CartInfo cartInfo : cartInfoList) {
            OrderItem orderItem = new OrderItem();
            orderItem.setSkuId(cartInfo.getSkuId());
            orderItem.setSkuName(cartInfo.getSkuName());
            orderItem.setSkuNum(cartInfo.getSkuNum());
            orderItem.setSkuPrice(cartInfo.getCartPrice());
            orderItem.setThumbImg(cartInfo.getImgUrl());
            orderItemList.add(orderItem);
        }
        // 获取订单支付总金额
        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderItem orderItem : orderItemList) {
            totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }
        TradeVo tradeVo = new TradeVo();
        tradeVo.setOrderItemList(orderItemList);
        tradeVo.setTotalAmount(totalAmount);
        return tradeVo;
    }

    // 提交订单
    @Override
    @Transactional
    public Long submitOrder(OrderInfoDto orderInfoDto) {
        // orderInfoDto 获取所有订单项list
        List<OrderItem> orderItemList = orderInfoDto.getOrderItemList();
        // 判断List<OrderItem>为空，抛出异常
        if (CollectionUtils.isEmpty(orderItemList)) {
            throw new CustomException(ResultCodeEnum.DATA_ERROR);
        }
        System.out.println("@@@@@@@111");
        // 检验商品库存是否充足
        for (OrderItem orderItem : orderItemList) {
            // 根据skuId获取sku信息，远程调用获取商品sku信息，包含库存量
            ProductSku productSku = productFeignClient.getBySkuId(orderItem.getSkuId());
            if (productSku == null) {
                throw new CustomException(ResultCodeEnum.DATA_ERROR);
            }
            // 检验每个orderItem库存量是否充足
            if (orderItem.getSkuNum().intValue() > productSku.getStockNum().intValue()) {
                throw new CustomException(ResultCodeEnum.STOCK_LESS);
            }
        }
        // 添加数据到order_info表
        // 封装数据到orderInfo对象
        // 远程调用：获取用户收货地址信息
        OrderInfo orderInfo = new OrderInfo();
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        // 订单编号
        orderInfo.setOrderNo(String.valueOf(System.currentTimeMillis()));
        // 用户id
        orderInfo.setUserId(userInfo.getId());
        // 用户昵称
        orderInfo.setNickName(userInfo.getNickName());
        // 封装收货地址信息
        Long userAddressId = orderInfoDto.getUserAddressId();
        // 远程调用，根据收货地址id，获取用户收货地址
        UserAddress userAddress = userFeignClient.getUserAddress(userAddressId);
        orderInfo.setReceiverName(userAddress.getName());
        orderInfo.setReceiverPhone(userAddress.getPhone());
        orderInfo.setReceiverTagName(userAddress.getTagName());
        orderInfo.setReceiverProvince(userAddress.getProvinceCode());
        orderInfo.setReceiverCity(userAddress.getCityCode());
        orderInfo.setReceiverDistrict(userAddress.getDistrictCode());
        orderInfo.setReceiverAddress(userAddress.getFullAddress());
        //订单金额
        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderItem orderItem : orderItemList) {
            totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }
        orderInfo.setTotalAmount(totalAmount);
        orderInfo.setCouponAmount(new BigDecimal(0));
        orderInfo.setOriginalTotalAmount(totalAmount);
        orderInfo.setFeightFee(orderInfoDto.getFeightFee());
        orderInfo.setPayType(2);
        orderInfo.setOrderStatus(0);
        // 保存到order_info表
        orderInfoMapper.save(orderInfo);
        // 添加数据到order_item表
        // 添加List<OrderItem>里面数据，把集合每个orderItem添加到表
        for (OrderItem orderItem : orderItemList) {
            // 设置对应订单id
            orderItem.setOrderId(orderInfo.getId());
            orderItemMapper.save(orderItem);
        }
        // 添加数据到order_log表
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(orderInfo.getId());
        orderLog.setProcessStatus(0);
        orderLog.setNote("提交订单");
        orderLogMapper.save(orderLog);

        // 远程调用：把生成订单商品，从购物车删除
        cartFeignClient.deleteChecked();
        // 返回订单id
        return orderInfo.getId();
    }

    // 获取订单信息
    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        return orderInfoMapper.getById(orderId);
    }

    // 立即购买
    @Override
    public TradeVo buy(Long skuId) {
        // 封装订单项集合
        List<OrderItem> orderItemList = new ArrayList<>();
        ProductSku productSku = productFeignClient.getBySkuId(skuId);
        OrderItem orderItem = new OrderItem();
        orderItem.setSkuId(skuId);
        orderItem.setSkuName(productSku.getSkuName());
        orderItem.setSkuNum(1);
        orderItem.setSkuPrice(productSku.getSalePrice());
        orderItem.setThumbImg(productSku.getThumbImg());
        orderItemList.add(orderItem);
        TradeVo tradeVo = new TradeVo();
        tradeVo.setOrderItemList(orderItemList);
        tradeVo.setTotalAmount(productSku.getSalePrice());
        return tradeVo;
    }

    // 获取订单分页列表
    @Override
    public PageInfo<OrderInfo> findOrderPage(Integer page, Integer limit, Integer orderStatus) {
        PageHelper.startPage(page, limit);
        // 查询订单信息
        Long userId = AuthContextUtil.getUserInfo().getId();
        List<OrderInfo> orderInfoList = orderInfoMapper.findUserPage(userId, orderStatus);
        // 订单里面所有订单项
        orderInfoList.forEach(orderInfo -> {
            // 订单id查询订单里面订单项
            List<OrderItem> orderItemList = orderItemMapper.findByOrderId(orderInfo.getId());
            // 封装
            orderInfo.setOrderItemList(orderItemList);
        });
        return new PageInfo<>(orderInfoList);
    }

    // 远程调用：根据订单编号获取订单信息
    @Override
    public OrderInfo getOrderInfoByOrderNo(String orderNo) {
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByOrderNo(orderNo);
        List<OrderItem> orderItemList = orderItemMapper.findByOrderId(orderInfo.getId());
        orderInfo.setOrderItemList(orderItemList);
        return orderInfo;
    }

    // 远程调用，更行订单状态
    @Override
    public String updateOrderStatus(String orderNo) {
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByOrderNo(orderNo);
        orderInfo.setOrderStatus(1);
        orderInfo.setPaymentTime(new Date());
        orderInfo.setPayType(2);
        orderInfoMapper.updateById(orderInfo);
        return "ok";
    }
}
